#ifndef NETLIB_ATOMIC_H
#define NETLIB_ATOMIC_H

// 原子计数类，线程安全类
// 使用原子操作时，编译器需加上 -march=cpu-type

#include "noncopyable.h"

#include <stdint.h>

namespace netlib
{

namespace detail
{

template<typename T>
class AtomicIntegerT : noncopyable // 不能拷贝复制
{
public:
    AtomicIntegerT() : value_(0)
    {}

    // 原子操作返回value_的值
    T get() { return __sync_val_compare_and_swap(&value_, 0, 0); }

    // 原子操作先返回value_的值，然后value_加上x
    T getAndAdd(T x) { return __sync_fetch_and_add(&value_, x); }

    // 原子操作返回value_+x的值
    T addAndGet(T x) { return getAndAdd(x) + x; }

    // 原子操作，自增
    T incrementAndGet() { return addAndGet(1); }

    // 原子操作，自减
    T decrementAndGet() { return addAndGet(-1); }

    // 原子操作，value_加上x
    void add(T x) { getAndAdd(x); }

    void increment() { incrementAndGet(); }

    void decrement() { decrementAndGet(); }

    // 原子操作，返回原来的值，然后将value_的值设置为newValue
    T getAndSet(T newValue) { return __sync_lock_test_and_set(&value_, newValue); }

private:
    volatile T value_;

}; // class AtomicIntegerT end

}  // namespace detail end

typedef detail::AtomicIntegerT<int32_t> AtomicInt32;
typedef detail::AtomicIntegerT<int64_t> AtomicInt64;

}  // namespace netlib end

#endif